package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.*;
import com.example.demo.entity.vo.DemandVo;
import com.example.demo.exception.bizException.BizException;
import com.example.demo.mapper.DemandMapper;
import com.example.demo.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
* <p>
*  服务实现类
* </p>
*
* @author cy
* @since 2020-08-01
*/
@Slf4j
@Service
public class DemandServiceImpl extends ServiceImpl<DemandMapper, Demand> implements DemandService {

    @Autowired
    private UserService userService;

    @Autowired
    private DAccessoryService dAccessoryService;

    @Autowired
    private InformationService informationService;

    @Autowired
    private FileService fileService;

    @Autowired
    private CollectService collectService;


    @Override
    public Page<DemandVo> listDemandsByPage(int page, int pageSize,
                                            String factor,
                                            String demandType,
                                            boolean price, boolean priceAsc,
                                            Integer state,
                                            Integer uId,
                                            boolean time, boolean timeAsc,
                                            Integer timeState) {
        log.info("正在执行分页查询demand: page = {} pageSize = {} factor = {} price={} priceAsc={} check={}",page,pageSize,factor,price,priceAsc,state);
        QueryWrapper<Demand> queryWrapper =  new QueryWrapper<Demand>().
                //需求状态（通过、审核、不通过）
                eq(state!=null,"state",state).
                eq(demandType.length()!=0,"demand_type",demandType).
                //需求所属用户
                eq(uId!=null,"u_id",uId);
        if(timeState!=null){
            if(timeState.equals(Demand.NO_APPLY_TIME)){
                queryWrapper.ge("begin_time", LocalDate.now());
            }else if(timeState.equals(Demand.APPLYING)){
                queryWrapper.le("begin_time",LocalDate.now()).ge("end_time",LocalDate.now());
            }else if(timeState.equals(Demand.APPLY_END)){
                queryWrapper.le("end_time",LocalDate.now());
            }
        }
        //or()放到后面来，不然前面条件会变失效
        queryWrapper.and(factor.length()!=0,w->w.like(factor.length()!=0,"demand_name", factor)).
                orderBy(time,timeAsc,"begin_time").
                orderBy(price,priceAsc,"price");
        Page<Demand> result = super.page(new Page<>(page, pageSize),queryWrapper);
        log.info("分页查询demand完毕: 结果数 = {} ",result.getRecords().size());
        Page<DemandVo> voPage=new Page<>();
        List<DemandVo> voList=new ArrayList<>(result.getRecords().size());
        for(Demand demand:result.getRecords()){
            DemandVo demandVo = getDemandVoByDemand(demand);
            voList.add(demandVo);
        }
        BeanUtils.copyProperties(result,voPage);
        voPage.setRecords(voList);
        return voPage;
    }

    private DemandVo getDemandVoByDemand(Demand demand) {
        DemandVo demandVo = new DemandVo();
        demandVo.setDemand(demand);
        //去除密码
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<User>().select(User.class, info -> !"password".equals(info.getColumn())).
                eq("user_id", demand.getUId());
        demandVo.setUser(userService.getByQueryWrapper(userQueryWrapper));
        return demandVo;
    }

    @Override
    public DemandVo getDemandById(int id) {
        log.info("正在查询demand中id为{}的数据",id);
        Demand demand = super.getById(id);
        if(demand==null){
            return null;
        }
        log.info("查询id为{}的demand{}",id,(null == demand?"无结果":"成功"));
        return getDemandVoByDemand(demand);
    }

    @Override
    public Demand getJustDemandById(int id) {
        Demand demand = super.getById(id);
        return demand;
    }

    @Override
    public int insertDemand(Demand demand) {
        demand.setState(Demand.CHECK);
        log.info("正在插入demand");
        if (super.save(demand)) {
            log.info("插入demand成功,id为{}",demand.getDemandId());
            return demand.getDemandId();
        } else {
            log.error("插入demand失败");
            throw new BizException("添加失败");
        }
    }

    @Transactional
    @Override
    public int deleteDemandById(int id,int userId) {
        log.info("正在删除id为{}的demand",id);
        QueryWrapper<Demand> queryWrapper=new QueryWrapper<Demand>().select("u_id").eq("demand_id",id);
        Demand demand=super.getOne(queryWrapper);
        if(!demand.getUId().equals(userId)){
            log.info("该{}需求不是{}用户的，无法删除",id,userId);
            throw new BizException("该需求不是这个用户的，无法删除");
        }
        //获取需求的所有附件，删除附件文件
        List<DAccessory> dAccessoryByDIds = dAccessoryService.getDAccessoryByDId(id);
        for(DAccessory dAccessory:dAccessoryByDIds){
            fileService.delete(dAccessory.getAccessoryName());
        }
        collectService.deleteCollectByForeignId(id, Collect.DEMAND_TYPE);
        if (super.removeById(id)) {
            log.info("删除id为{}的demand成功",id);
            return id;
        } else {
            log.error("删除id为{}的demand失败",id);
            throw new BizException("删除失败[id=" + id + "]");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateDemand(Demand demand) {
        log.info("正在更新id为{}的demand",demand.getDemandId());
        Demand user=super.getById(demand.getDemandId());
        if(!demand.getUId().equals(user.getUId())){
            throw new BizException("这个需求不是该用户的");
        }
        if(demand.getState() == null ||  demand.getState() != 2) {
            demand.setState(Demand.CHECK);
        }
        if (super.updateById(demand)) {
            log.info("更新d为{}的demand成功",demand.getDemandId());
            return demand.getDemandId();
        } else {
            log.error("更新id为{}的demand失败",demand.getDemandId());
            throw new BizException("更新失败[id=" + demand.getDemandId() + "]");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int checkAchieve(Demand demand) {
        log.info("demand中id为{}正在通过审核",demand.getDemandId());
        //获取数据库对应需求，
        Demand inDemand=super.getById(demand.getDemandId());
        //设置给用户的消息通知
        Information information=new Information();
        information.setTime(LocalDateTime.now());
        information.setUserId(inDemand.getUId());
        //判断需求审核状态
        if(demand.getState()==Demand.NO_PASS){
            information.setMessage("尊敬的用户您好，您的一个需求审核未通过，您可以对需求内容进行修改后再次提交申请或者联系管理员。");
        }else if(demand.getState()==Demand.PASS){
            information.setMessage("尊敬的用户您好，您的一个需求审核已通过。");
        }else {
            throw new BizException("需求状态错误");
        }
        if (super.updateById(demand)) {
            log.info("审核id为{}的demand成功,通过与否{}",demand.getDemandId(),demand.getState()==Demand.PASS);
            informationService.insertInformation(information);
            return demand.getDemandId();
        } else {
            log.error("审核id为{}的demand失败",demand.getDemandId());
            throw new BizException("更新失败[id=" + demand.getDemandId() + "]");
        }
    }

    @Override
    public int importDemand(String fileName, MultipartFile file, int userId) throws IOException {
        //后面需要再补充
        return 0;
    }

    @Override
    public int UncheckedNum() {
        log.info("正在查询未审核的需求数量");
        QueryWrapper<Demand> queryWrapper=new QueryWrapper<Demand>().eq("state",0);
        List<Demand> patentList = this.getBaseMapper().selectList(queryWrapper);
        return  patentList.size();
    }

}
